﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using MvvmFoundation.Wpf;
using System.Windows.Controls;
using System.Windows;
using System.ServiceModel;
using Revis.VClinicNet.UI.External.Client.Service;
using Revis.VClinicNet.UI.External.Client.View;

namespace Revis.VClinicNet.UI.External.Client.ViewModel
{
    public class MainWindowViewModel : ObservableObject
    {
        private Service.IPatientService _patientService;
        private readonly EventHandler<WorkspaceStateChangeEventArgs> WorkspaceStateChangedEventHandler;

        public MainWindowViewModel()
        {
            WorkspaceStateChangedEventHandler = new EventHandler<WorkspaceStateChangeEventArgs>(WorkspaceStateChange);
            ResetViewModel();
        }

        #region Content bindings

        private IWorkspaceControl _activeWorkspaceControl = null;
        private IWorkspaceControl ActiveWorkspaceControl
        {
            get { return _activeWorkspaceControl; }
            set
            {
                _activeWorkspaceControl = value;
                RaisePropertyChanged("ActiveWorkspace");
                RaisePropertyChanged("ActiveWorkspaceTitle");
            }
        }

        public UserControl ActiveWorkspace
        {
            get { return _activeWorkspaceControl != null ? _activeWorkspaceControl.Workspace : null; }
        }

        public string ActiveWorkspaceTitle
        {
            get { return _activeWorkspaceControl != null ? _activeWorkspaceControl.DisplayName : String.Empty; }
        }

        private ReadOnlyCollection<IWorkspaceCommand> _workspaceCommands = null;
        public ReadOnlyCollection<IWorkspaceCommand> WorkspaceCommands
        {
            get
            {
                return _workspaceCommands;
            }
            set
            {
                _workspaceCommands = value;
                RaisePropertyChanged("WorkspaceCommands");
            }
        }

        private Visibility _isRequesting = Visibility.Hidden;
        public Visibility IsRequesting
        {
            get { return _isRequesting; }
            set
            {
                if (_isRequesting == value) {
                    return;
                }
                _isRequesting = value;
                RaisePropertyChanged("IsRequesting");
            }
        }

        private string _status = String.Empty;
        public string Status
        {
            get { return _status; }
            set
            {
                if (_status == value) {
                    return;
                }
                _status = value;
                RaisePropertyChanged("Status");
            }
        }

        #endregion

        #region Private methods


        private void WorkspaceStateChange(object sender, WorkspaceStateChangeEventArgs args)
        {
            IsRequesting = args.State == RequestState.Requesting ? Visibility.Visible : Visibility.Hidden;
            Status = args.Status;
            if (args.State == RequestState.Faulted) {
                ResetViewModel();
            }
            if (sender.GetType() == typeof(LoginViewModel) && args.State == RequestState.Success) {
                LoadWorkspaceCommands();
            }
        }

        private void ResetViewModel()
        {
            if (_patientService != null) {
                ClientBase<IPatientService> client = (ClientBase<IPatientService>)_patientService;
                try {
                    client.Close();
                } catch (Exception) {
                    client.Abort();
                }
            }
            //_patientService = new FakePatientService();
            _patientService = new PatientServiceClient();

            LoadLoginWorkspace();

            IsRequesting = Visibility.Hidden;
        }

        private void ResetActiveWorkspaceControl()
        {
            if (ActiveWorkspaceControl != null) {
                ActiveWorkspaceControl.OnStateChanged -= WorkspaceStateChangedEventHandler;
            }
            ActiveWorkspaceControl = null;
        }

        private void LoadLoginWorkspace()
        {
            ResetActiveWorkspaceControl();
            WorkspaceCommands = new ReadOnlyCollection<IWorkspaceCommand>(new List<IWorkspaceCommand>() {
                new WorkspaceCommandViewModel<Login, LoginViewModel>("Logowanie", delegate{})
            });
            CreateWorkspaceControl(WorkspaceCommands.First());
        }

        private void LoadWorkspaceCommands()
        {
            ResetActiveWorkspaceControl();
            WorkspaceCommands = new ReadOnlyCollection<IWorkspaceCommand>(new List<IWorkspaceCommand>() {                    
                new WorkspaceCommandViewModel<View.Profile, ProfileViewModel>("Profil", CreateWorkspaceControl),
                new WorkspaceCommandViewModel<View.Visits, VisitsViewModel>("Wizyty", CreateWorkspaceControl),
                new WorkspaceCommandViewModel<View.Doctors, DoctorsViewModel>("Lekarze", CreateWorkspaceControl),
                new WorkspaceCommandViewModel<View.Card, CardViewModel>("Kartoteka", CreateWorkspaceControl),
                new WorkspaceCommandViewModel<View.ChangePassword, ChangePasswordViewModel>("Zmień hasło", CreateWorkspaceControl),
                new WorkspaceCommandViewModel<View.Login, LoginViewModel>("Wyloguj", LogoutUser)
            });
            CreateWorkspaceControl(WorkspaceCommands.First());
        }

        private void LogoutUser(IWorkspaceCommand command)
        {
            try {
                _patientService.Logout();
            } catch (Exception) { }
            ResetViewModel();
            Status = "Użytkownik wylogowany";
        }

        private void CreateWorkspaceControl(IWorkspaceCommand command)
        {
            ResetActiveWorkspaceControl();
            IWorkspaceControl viewModel = command.Create(_patientService);
            viewModel.OnStateChanged += WorkspaceStateChangedEventHandler;
            ActiveWorkspaceControl = viewModel;
            viewModel.Run();
        }

        #endregion
    }
}
